package com.xncoding.websocket.javax.demo1.Handler;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xncoding.websocket.javax.demo1.commons.MessageType;
import com.xncoding.websocket.javax.demo1.model.AbstractMessage;
import com.xncoding.websocket.javax.demo1.model.PersonMessage;
import com.xncoding.websocket.javax.demo1.model.PingMessage;
import com.xncoding.websocket.javax.demo1.model.SystemMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class WsMessageDecoder implements  Decoder.Text<AbstractMessage> {

    private static Logger logger = LoggerFactory.getLogger(WsMessageDecoder.class) ;
    private static Set<String> msgTypes = new HashSet<>() ;

    static {
        msgTypes.add(MessageType.PING.getType()) ;
        msgTypes.add(MessageType.SYSTEM.getType()) ;
        msgTypes.add(MessageType.PERSON.getType()) ;
    }
    @Override
    @SuppressWarnings("unchecked")
    public AbstractMessage decode(String s) throws DecodeException {
        AbstractMessage message = null ;
        try {
            ObjectMapper mapper = new ObjectMapper() ;
            Map<String,String> map = mapper.readValue(s, Map.class) ;
            String type = map.get("type") ;
            switch(type) {
                case "0000":
                    message = mapper.readValue(s, SystemMessage.class) ;
                    break;
                case "0001":
                    message = mapper.readValue(s, PingMessage.class) ;
                    break;
                case "2001":
                    message = mapper.readValue(s, PersonMessage.class) ;
                    break;
            }
        } catch (JsonProcessingException e) {
            logger.error("JSON处理错误：{}", e) ;
        }
        return message ;
    }

    // 该方法判断消息是否可以被解码（转换）
    @Override
    @SuppressWarnings("unchecked")
    public boolean willDecode(String s) {
        Map<String, String> map = new HashMap<>() ;
        try {
            map = new ObjectMapper().readValue(s, Map.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        logger.debug("检查消息：【" + s + "】是否可以解码") ;
        String type = map.get("type") ;
        if (StringUtils.isEmpty(type) || !msgTypes.contains(type)) {
            return false ;
        }
        return true ;
    }
    @Override
    public void init(EndpointConfig endpointConfig) {
    }
    @Override
    public void destroy() {
    }
}